import {useCallback, useState} from 'react'

export interface Room {
  name: string
  cameraId?: number
  id?: number
  del?: boolean
}

export interface Floor {
  name: string
  rooms: Room[]
  id?: number
  del?: boolean
}

export interface Building {
  name: string
  adminId?: number
  telephone: string
  floors: Floor[]
}

export function useBuildingEdit(options?: { building?: Building }) {
  const [building, setBuilding] = useState<Building>(
    options?.building ??
      ({
        name: '',
        telephone: '',
        floors: [],
      } as Building),
  )

  const inputBuildingName = (name: Building['name']) => {
    setBuilding((oldData) => {
      const newData = { ...oldData }
      newData.name = name
      return newData
    })
  }

  const chooseBuildingAdminId = (id: Building['adminId']) => {
    setBuilding((oldData) => {
      const newData = { ...oldData }
      newData.adminId = id
      return newData
    })
  }

  const inputBuildingTelephone = (telephone: Building['telephone']) => {
    setBuilding((oldData) => {
      const newData = { ...oldData }
      newData.telephone = telephone
      return newData
    })
  }

  const inputFloorName = (index: number, name: Floor['name']) => {
    setBuilding((oldData) => {
      const newData = { ...oldData }
      const floor = newData.floors[index]
      if (!floor) return oldData
      floor.name = name
      return newData
    })
  }

  const addFloor = () => {
    setBuilding((oldData) => {
      return {
        ...oldData,
        floors: [ { name: '', rooms: [] }, ...oldData.floors],
      }
    })
  }

  const addRoom = useCallback((floorIndex: number) => {
    let count = 0;
    setBuilding((oldData) => {
      if (count > 0) return oldData;
      const newData = { ...oldData };
      const floor = newData.floors[floorIndex];
      if (!floor) return oldData;
      floor.rooms.unshift({ name: '' }); // Add the new room at the beginning
      count += 1;
      return newData;
    });
  }, []);

  const renameRoom = (floorIndex: number, roomIndex: number, name: string) => {
    setBuilding((oldData) => {
      const newData = { ...oldData }
      const floor = newData.floors[floorIndex]
      if (!floor) return oldData
      const room = floor.rooms[roomIndex]
      if (!room) return oldData
      room.name = name
      return newData
    })
  }

  const updateCameraId = (
    floorIndex: number,
    roomIndex: number,
    cameraId: number,
  ) => {
    setBuilding((oldData) => {
      const newData = { ...oldData }
      const floor = newData.floors[floorIndex]
      if (!floor) return oldData
      const room = floor.rooms[roomIndex]
      if (!room) return oldData
      room.cameraId = cameraId
      return newData
    })
  }

  const removeRoom = (floorIndex: number, roomIndex: number) => {
    let count = 0
    setBuilding((oldData) => {
      if (count > 0) return oldData
      const newData = { ...oldData }
      const floor = newData.floors[floorIndex]
      if (!floor) return oldData
      floor.rooms.splice(roomIndex, 1)
      count += 1
      return newData
    })
  }

  const removeFloor = (floorIndex: number) => {
    setBuilding((oldData) => {
      const newData = { ...oldData }
      newData.floors.splice(floorIndex, 1)
      return newData
    })
  }

  const updateRoom = (
    floorIndex: number,
    roomIndex: number,
    cameraId: number,
  ) => {
    setBuilding((oldData) => {
      const newData = { ...oldData }
      const floor = newData.floors[floorIndex]
      if (!floor) return oldData
      const room = floor.rooms[roomIndex]
      if (!room) return oldData
      room.cameraId = cameraId
      return newData
    })
  }

  const setDelFloor = (floorIndex: number) => {
    setBuilding((oldData) => {
      const newData = { ...oldData }
      const floor = newData.floors[floorIndex]
      floor.del = true
      return newData
    })
  }

  const setDelRoom = (floorIndex: number, roomIndex: number) => {
    setBuilding((oldData) => {
      const newData = { ...oldData }
      const floor = newData.floors[floorIndex]
      if (!floor) return oldData
      const room = floor.rooms[roomIndex]
      if (!room) return oldData
      room.del = true
      return newData
    })
  }

  return {
    building,
    inputBuildingName,
    chooseBuildingAdminId,
    inputBuildingTelephone,
    inputFloorName,
    addFloor,
    addRoom,
    removeFloor,
    renameRoom,
    removeRoom,
    updateCameraId,
    setBuilding,
    updateRoom,
    setDelFloor,
    setDelRoom,
  }
}
